package net.crowtheries.wirelessrouting;

import java.util.HashMap;
import java.util.HashSet;


import ptolemy.actor.TypedAtomicActor;
import ptolemy.data.StringToken;
import ptolemy.data.Token;
import ptolemy.data.expr.StringParameter;
import ptolemy.data.type.BaseType;
import ptolemy.domains.wireless.kernel.WirelessIOPort;
import ptolemy.kernel.CompositeEntity;
import ptolemy.kernel.util.IllegalActionException;
import ptolemy.kernel.util.NameDuplicationException;

public class RoutesManager extends TypedAtomicActor{
	public RoutesManager(CompositeEntity container,String name) throws IllegalActionException, NameDuplicationException{
		super(container,name);
		reqHop=new WirelessIOPort(this,"reqHop",true,false);
		nxtHop=new WirelessIOPort(this,"nxtHop",false,true);
		addEntry=new WirelessIOPort(this,"addEntry",true,false);
		reqRoute=new WirelessIOPort(this,"reqRoute",false,true);
		
		_routingTable=new HashMap<String, Object[]>();
	}
	
	///////// Ports /////
	/**
	 * 
	 */
	WirelessIOPort reqHop;
	WirelessIOPort nxtHop;
	WirelessIOPort reqRoute;
	WirelessIOPort addEntry;
	
	///////// Private vars //////
	/**
	 * Contains the routes :
	 * key=DST_ADR
	 * Value= [ NXT_HOP , DST_SEQ , LIFE ]
	 */
	HashMap<String, Object[]> _routingTable;
	
	/**
	 * Contains a cache of all the requests coming from FH
	 * it'll be to avoid sending "useless" messages to FH 
	 * for example when we make reverse routes
	 */
	HashSet<StringToken> _cacheIP=new HashSet<StringToken>();
	
	String _localIP;
	
	public void initialize(){
		StringParameter localip=(StringParameter)this.getContainer().getAttribute("localIP");
		_localIP=localip.getValueAsString();
		// jsut for test
		_routingTable.put("192.168.1.3", new Object[]{"192.168.1.2",5,55});
	}
	
	public void fire() throws IllegalActionException{
		
		/*
		 * If we get a request for a route
		 */
		if(reqHop.hasToken(0)){			
			StringToken dstIP=(StringToken)reqHop.get(0);
			
			//we add the IP to the Cache
			_cacheIP.add(dstIP);
			
			//if the destination IP is in te table we send it directly to the "nxtHop" port to be used by the FlowHandler 
			if(_routingTable.get(dstIP.stringValue())!=null)
				nxtHop.send(0, new StringToken((String)_routingTable.get(dstIP.stringValue())[0]));
			
			//if we dont have it, we forward the ip to the protocol manager so he handles it by making the RREQ...
			else
				reqRoute.send(0, dstIP);
		}
		
		if(addEntry.hasToken(0)){
			if(_cacheIP.contains(55))
			System.out.println(addEntry.get(0));
		}
	}
	

}
